package com.gcosc.hly.codejava.Utils;

import com.gcosc.hly.codejava.exception.BusinessException;
import com.gcosc.hly.codejava.result.Code;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.util.Date;
import java.util.Map;
import java.util.Set;

/**
 * 邮件业务类
 * @author qzz
 */
@Component
@Log4j2
public class MailUtils {

    /**
     * 注入邮件工具类
     */
    @Autowired
    private JavaMailSenderImpl javaMailSender;

    @Value("${spring.mail.username}")
    private String sendMailer;

    /**
     * 检测邮件信息类
     * @param to
     * @param subject
     * @param text
     */
    private void checkMail(String to,String subject,String text){
        if(StringUtils.isEmpty(to)){
            throw new BusinessException(Code.BUSINESS_ERR ,"邮件收信人不能为空");
        }
        if(StringUtils.isEmpty(subject)){
            throw new BusinessException(Code.BUSINESS_ERR ,"邮件主题不能为空");
        }
        if(StringUtils.isEmpty(text)){
            throw new BusinessException(Code.BUSINESS_ERR ,"邮件内容不能为空");
        }
    }

    /**
     * 发送纯文本邮件
     * @param to
     * @param subject
     * @param text
     */
    public void sendTextMailMessage(String to,String subject,String text){

        try {
            //true 代表支持复杂的类型
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(javaMailSender.createMimeMessage(),true);
            //邮件发信人
            mimeMessageHelper.setFrom(sendMailer);
            //邮件收信人  1或多个
            mimeMessageHelper.setTo(to.split(","));
            //邮件主题
            mimeMessageHelper.setSubject(subject);
            //邮件内容
            mimeMessageHelper.setText(text);
            //邮件发送时间
            mimeMessageHelper.setSentDate(new Date());

            //发送邮件
            javaMailSender.send(mimeMessageHelper.getMimeMessage());
            System.out.println("发送邮件成功："+sendMailer+"->"+to);

        } catch (MessagingException e) {
            e.printStackTrace();
            log.error(e.getMessage());
            throw new BusinessException(Code.BUSINESS_ERR, "邮箱不正确，邮件发送失败");
        }
    }


    /**
     * 发送html邮件
     * @param to
     * @param subject
     * @param content
     */
    public void sendHtmlMailMessage(String to,String subject,String content){


        try {
            //true 代表支持复杂的类型
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(javaMailSender.createMimeMessage(),true);
            //邮件发信人
            mimeMessageHelper.setFrom(sendMailer);
            //邮件收信人  1或多个
            mimeMessageHelper.setTo(to.split(","));
            //邮件主题
            mimeMessageHelper.setSubject(subject);
            //邮件内容   true 代表支持html
            mimeMessageHelper.setText(content,true);
            //邮件发送时间
            mimeMessageHelper.setSentDate(new Date());

            //发送邮件
            javaMailSender.send(mimeMessageHelper.getMimeMessage());
            System.out.println("发送邮件成功："+sendMailer+"->"+to);

        } catch (MessagingException e) {
            log.error(e.getMessage());
            throw new BusinessException(Code.BUSINESS_ERR, "邮箱不正确，邮件发送失败");
        }
    }

    public void sendAttachmentMailMessage(String to,String subject,String content,String filePath){
        sendAttachmentMailMessage(to, subject, content, new String[]{filePath}, null);
    }

    public void sendAttachmentMailMessage(String to,String subject,String content, Map<String, String> map){
        sendAttachmentMailMessage(to, subject, content, new String[0], map);
    }

    public void sendAttachmentMailMessage(String to,String subject,String content,String[] filePath){
        sendAttachmentMailMessage(to, subject, content, filePath, null);
    }

    /**
     * 发送带附件的邮件
     * @param to      邮件收信人
     * @param subject 邮件主题
     * @param content 邮件内容
     * @param filePath 附件路径
     * @param map 正文引用图片
     */
    public void sendAttachmentMailMessage(String to, String subject, String content, String[] filePath, Map<String, String> map){
        try {
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            //true 代表支持复杂的类型
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage ,true);
            //邮件发信人
            mimeMessageHelper.setFrom(sendMailer);
            //邮件收信人  1或多个
            mimeMessageHelper.setTo(to.split(","));
            //邮件主题
            mimeMessageHelper.setSubject(subject);
            //邮件发送时间
            mimeMessageHelper.setSentDate(new Date());


            MimeMultipart allMultipart = new MimeMultipart();

            //创建代表邮件正文和附件的各个MimeBodyPart对象
            MimeBodyPart contentPart = createContent(content, map);
            allMultipart.addBodyPart(contentPart);

            //创建用于组合邮件正文和附件的MimeMultipart对象
            for (int i = 0; i < filePath.length; i++) {
                allMultipart.addBodyPart(createAttachment(filePath[i]));
            }

            //设置整个邮件内容为最终组合出的MimeMultipart对象
            mimeMessage.setContent(allMultipart);
            mimeMessage.saveChanges();

            javaMailSender.send(mimeMessage);
            log.info("发送邮件成功："+sendMailer+"->"+to);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            throw new BusinessException(Code.BUSINESS_ERR, "邮箱不正确，邮件发送失败");
        }
    }

    /**
     * 功能描述：邮件附件
     * @param filename 文件路径
     * @return {@link MimeBodyPart}
     * @author wi-gang
     * @date 2021/12/29 2:50 下午
     */
    public MimeBodyPart createAttachment(String filename) throws Exception {
        //创建保存附件的MimeBodyPart对象，并加入附件内容和相应的信息
        MimeBodyPart attachPart = new MimeBodyPart();
        FileDataSource fsd = new FileDataSource(filename);
        attachPart.setDataHandler(new DataHandler(fsd));
        attachPart.setFileName(fsd.getName());
        return attachPart;
    }

    /**
     * 功能描述：文本内嵌图片
     * @param body html格式的文本内容
     * @param map 图片集合
     * @return {@link MimeBodyPart}
     * @author wi-gang
     * @date 2021/12/29 2:50 下午
     */
    public MimeBodyPart createContent(String body, Map<String, String> map) throws Exception {
        //创建代表组合Mime消息的MimeMultipart对象，将该MimeMultipart对象保存到MimeBodyPart对象
        MimeBodyPart contentPart = new MimeBodyPart();
        MimeMultipart contentMultipart = new MimeMultipart("related");

        //创建用于保存HTML正文的MimeBodyPart对象，并将它保存到MimeMultipart中
        MimeBodyPart htmlBodyPart = new MimeBodyPart();
        htmlBodyPart.setContent(body, "text/html;charset=UTF-8");
        contentMultipart.addBodyPart(htmlBodyPart);

        if (map != null && map.size() > 0) {
            Set<Map.Entry<String, String>> set = map.entrySet();
            for (Map.Entry<String, String> entry : set) {
                //创建用于保存图片的MimeBodyPart对象，并将它保存到MimeMultipart中
                MimeBodyPart gifBodyPart = new MimeBodyPart();
                FileDataSource fds = new FileDataSource(entry.getValue());//图片所在的目录的绝对路径

                gifBodyPart.setDataHandler(new DataHandler(fds));
                gifBodyPart.setContentID(entry.getKey());    //cid的值
                contentMultipart.addBodyPart(gifBodyPart);
            }
        }

        //将MimeMultipart对象保存到MimeBodyPart对象
        contentPart.setContent(contentMultipart);
        return contentPart;
    }
}
